//
// bufdb_server.cpp
// ~~~~~~~~~~~~~~~~~~
//
// Copyright (c) 2010 The bufdb Team
//

#include <ctime>
#include <iostream>
#include <string>
#include <boost/asio.hpp>

#include <stdio.h>  
#include <SQLAPI.h> // main SQLAPI++ header

#include "database.pb.h"
#include <google/protobuf/message.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/text_format.h>
using namespace google::protobuf;
using boost::asio::ip::tcp;

void determineFieldTypes(const Descriptor*, int);
void determineNestedFields(const Descriptor*);
void initializeDB();

int main(int argc, void *argv[])
{
  try
  {
    boost::asio::io_service io_service;

    tcp::endpoint endpoint(tcp::v4(), 13);
    tcp::acceptor acceptor(io_service, endpoint);

    for (;;)
    {
      tcp::iostream stream;
      acceptor.accept(*stream.rdbuf());

      // parse the message into the class
      db::Database *msg = new db::Database();
      if (!msg->ParseFromIstream(&stream)) {
        std::cerr << "Failed to parse" << std::endl;
        exit(1);
      }

      // use the class here
      msg->PrintDebugString();
		/*
		
		
		*/
    }
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}

void determineFieldTypes(const Descriptor* msgDescript, int maxFieldCnt)
{
	for(int fieldCnt = 0; fieldCnt < maxFieldCnt; fieldCnt++)
	{
		const FieldDescriptor* msgField = msgDescript->field(fieldCnt);
		

		if(msgField->type()==FieldDescriptor::TYPE_BOOL)
		{
			cout<<msgField->name()<<" is a Boolean."<<endl;
		}
		else if(msgField->type()==FieldDescriptor::TYPE_STRING)
		{
			cout<<msgField->name()<<" is a String."<<endl;
			//getStringFromField
		}
		else if(msgField->type()==FieldDescriptor::TYPE_INT32)
		{
			cout<<msgField->name()<<" is an INT32."<<endl;
		}
		else if(msgField->type()==FieldDescriptor::TYPE_FLOAT)
		{
			cout<<msgField->name()<<" is a Float."<<endl;
		}
		else if(msgField->type()==FieldDescriptor::TYPE_DOUBLE)
		{
			cout<<msgField->name()<<" is a Double."<<endl;
		}						
		else if(msgField->type()==FieldDescriptor::TYPE_MESSAGE)
		{
			cout<<msgField->name()<<" is a nested Message."<<endl;
		}						

	}
}

void determineNestedFields(const Descriptor* msgDescript)
{
	for(int nestedCnt = 0; nestedCnt < msgDescript->nested_type_count(); nestedCnt++)
	{
		const Descriptor* nestedMsg = msgDescript->nested_type(nestedCnt);
		
		cout<<"Nested message "<<nestedMsg->name()<<" has the following fields: "<<"\n";
		
		determineFieldTypes(nestedMsg, nestedMsg->field_count());	
		
		
	}	
}

void initializeDB()
{
	//*************************************************************************
	//							CONNECT TO POSTGRESQL 
	//*************************************************************************
	/* Create SAconnection object con */
	SAConnection con;
	
	/*Set Client of Object con to PostgreSQL */
	con.setClient(SA_PostgreSQL_Client);

	/* Get Client Command to ensure PostgreSQL was assigned as client*/
	con.Client();

	/* Open database connection */
	con.Connect("localhost@", "postgres", "Kollsman1", SA_PostgreSQL_Client);

	/* Check the status of the database */
	while(con.isConnected()){
		cout<<"good to go"<< endl;
		break;
	}
}
